// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#include "mk_header.h"
#include "mk_view_frustum.h"
#include "mk_math.h"

namespace MK3DE
{
	void CViewFrustum::ExtractViewFrustum(D3DXMATRIX& viewProj)
	{
		// left
		_viewFrustumPlane[VFP_LEFT].a = viewProj._14 + viewProj._11;
		_viewFrustumPlane[VFP_LEFT].b = viewProj._24 + viewProj._21;
		_viewFrustumPlane[VFP_LEFT].c = viewProj._34 + viewProj._31;
		_viewFrustumPlane[VFP_LEFT].d = viewProj._44 + viewProj._41;

		// right
		_viewFrustumPlane[VFP_RIGHT].a = viewProj._14 - viewProj._11;
		_viewFrustumPlane[VFP_RIGHT].b = viewProj._24 - viewProj._21;
		_viewFrustumPlane[VFP_RIGHT].c = viewProj._34 - viewProj._31;
		_viewFrustumPlane[VFP_RIGHT].d = viewProj._44 - viewProj._41;

		// top
		_viewFrustumPlane[VFP_TOP].a = viewProj._14 - viewProj._12;
		_viewFrustumPlane[VFP_TOP].b = viewProj._24 - viewProj._22;
		_viewFrustumPlane[VFP_TOP].c = viewProj._34 - viewProj._32;
		_viewFrustumPlane[VFP_TOP].d = viewProj._44 - viewProj._42;

		// bottom
		_viewFrustumPlane[VFP_BOTTOM].a = viewProj._14 + viewProj._12;
		_viewFrustumPlane[VFP_BOTTOM].b = viewProj._24 + viewProj._22;
		_viewFrustumPlane[VFP_BOTTOM].c = viewProj._34 + viewProj._32;
		_viewFrustumPlane[VFP_BOTTOM].d = viewProj._44 + viewProj._42;

		// near
		_viewFrustumPlane[VFP_NEAR].a = viewProj._13;
		_viewFrustumPlane[VFP_NEAR].b = viewProj._23;
		_viewFrustumPlane[VFP_NEAR].c = viewProj._33;
		_viewFrustumPlane[VFP_NEAR].d = viewProj._43;

		// far
		_viewFrustumPlane[VFP_FAR].a = viewProj._14 - viewProj._13;
		_viewFrustumPlane[VFP_FAR].b = viewProj._24 - viewProj._23;
		_viewFrustumPlane[VFP_FAR].c = viewProj._34 - viewProj._33;
		_viewFrustumPlane[VFP_FAR].d = viewProj._44 - viewProj._43;

		for (int i = 0; i < (int)VFP_MAX; ++i)
			D3DXPlaneNormalize(&_viewFrustumPlane[i], &_viewFrustumPlane[i]);
	}

	BOOL CViewFrustum::TestFrustumAABB(AABB& aabb)
	{
		D3DXVECTOR3 pts[8];
		aabb.Extract(pts, 8);

		for (int i = 0; i < (int)VFP_MAX; ++i)
		{
			if (TestPlanePoints(_viewFrustumPlane[i], pts, 8))
				continue;

			return FALSE;
		}

		for (std::vector<D3DXPLANE>::iterator i = _vecCustomPlane.begin(); i != _vecCustomPlane.end(); ++i)
		{
			D3DXPLANE& plane = *i;

			if (TestPlanePoints(plane, pts, 8))
				continue;

			return FALSE;
		}

		return TRUE;
	}
}